package com.ruyuan.o2o.groupbuy.pay.admin.service;

import com.github.pagehelper.PageHelper;
import com.ruyuan.o2o.groupbuy.common.BeanMapper;
import com.ruyuan.o2o.groupbuy.pay.admin.thread.GlobalThreadPool;
import com.ruyuan.o2o.groupbuy.common.TimeUtil;
import com.ruyuan.o2o.groupbuy.message.service.MessageTemplateService;
import com.ruyuan.o2o.groupbuy.order.service.OrderService;
import com.ruyuan.o2o.groupbuy.order.vo.OrderVO;
import com.ruyuan.o2o.groupbuy.overage.service.OverageService;
import com.ruyuan.o2o.groupbuy.pay.admin.dao.PayDao;
import com.ruyuan.o2o.groupbuy.pay.model.PayModel;
import com.ruyuan.o2o.groupbuy.pay.service.PayService;
import com.ruyuan.o2o.groupbuy.pay.vo.PayVO;
import com.ruyuan.o2o.groupbuy.points.service.PointsService;
import com.ruyuan.o2o.groupbuy.points.vo.PointsVO;
import com.ruyuan.o2o.groupbuy.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 处理支付信息服务的增删改查service组件
 *
 * @author ming qian
 */
@Service(version = "1.0.0", interfaceClass = PayService.class, cluster = "failfast", loadbalance = "roundrobin")
@Slf4j
public class PayServiceImpl implements PayService {

    @Autowired
    private PayDao payDao;

    @Reference(version = "1.0.0", interfaceClass = OverageService.class,
            cluster = "failfast", loadbalance = "roundrobin")
    private OverageService overageService;

    @Reference(version = "1.0.0", interfaceClass = OrderService.class,
            cluster = "failfast", loadbalance = "roundrobin")
    private OrderService orderService;

    @Reference(version = "1.0.0", interfaceClass = PointsService.class,
            cluster = "failfast", loadbalance = "roundrobin")
    private PointsService pointsService;

    @Reference(version = "1.0.0", interfaceClass = MessageTemplateService.class,
            cluster = "failfast", loadbalance = "roundrobin")
    private MessageTemplateService messageTemplateService;

    @Reference(version = "1.0.0", interfaceClass = UserService.class,
            cluster = "failfast", loadbalance = "roundrobin")
    private UserService userService;

    @Autowired
    private GlobalThreadPool globalThreadPool;

    private final int send_num = 5;

    /**
     * 创建支付信息
     * 可通过 0 会员余额 1 银联卡 2 支付宝 3 微信 等方式支付
     *
     * @param payVO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean save(PayVO payVO) {
        PayModel payModel = new PayModel();
        BeanMapper.copy(payVO, payModel);
        payModel.setPayTime(TimeUtil.format(System.currentTimeMillis()));

        OrderVO orderVO = orderService.findById(payModel.getOrderId());
        switch (payVO.getPayChannel()) {
            case 0:
                Double overage = overageService.findOverage(payVO.getUserId(), payVO.getStoreId());
                if (null == overage || overage < orderVO.getOrderPrice()) {
                    log.error("余额不足");
                    return Boolean.FALSE;
                }
                log.info("订单相关信息扣减余额");
                log.info("更新支付后的余额");
                payModel.setPayStatus(0);
                payModel.setPayPrice(orderVO.getOrderPrice());
                break;
            case 1:
                log.info("调用银联卡第三方接口");
                break;
            case 2:
                log.info("调用支付宝第三方接口");
                break;
            case 3:
                log.info("调用微信第三方接口");
                break;
            default:
                log.error("支付失败");
        }
        //  保存支付信息
        payDao.save(payModel);

        //  保存积分
        PointsVO pointsVO = new PointsVO();
        BeanMapper.copy(payVO, pointsVO);
        //  模拟消费完成加1000积分
        pointsVO.setPointsAdd(1000);
        pointsVO.setPointsTotal((null == pointsVO.getPointsTotal()) ? 0 : pointsVO.getPointsTotal() + 1000);
        pointsService.save(pointsVO);

        log.info("用户:{} 支付成功,积分增加成功", payVO.getUserId());

        String phone = userService.findPhoneById(payVO.getUserId());

        //  模拟最大努力通知方案发送短信
        //  连续超过5次失败就不发了
        globalThreadPool.getThreadPool().submit(new Runnable() {
            @Override
            public void run() {
                try {
                    int sendCount = 0;
                    Boolean send = messageTemplateService.send(phone);
                    while (!send && sendCount < send_num) {
                        Thread.sleep(5000);
                        sendCount++;
                    }
                    log.info("手机号:{} 已发送短信", phone);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        return Boolean.TRUE;
    }

    /**
     * 分页查询支付信息
     *
     * @return
     */
    @Override
    public List<PayVO> listByPage(Integer pageNum, Integer pageSize) {
        List<PayVO> payVoS = new ArrayList<>();

        PageHelper.startPage(pageNum, pageSize);
        List<PayModel> payModels = payDao.listByPage();

        for (PayModel payModel : payModels) {
            PayVO payVO = new PayVO();
            BeanMapper.copy(payModel, payVO);
            payVoS.add(payVO);
        }

        return payVoS;
    }

}
